package com.beiding.jsonanalyzer.analyze.select;

import com.alibaba.fastjson.JSONObject;
import com.beiding.jsonanalyzer.Analyzer;
import com.beiding.jsonanalyzer.Key;
import com.beiding.jsonanalyzer.analyze.Fetcher;
import com.beiding.jsonanalyzer.analyze.Undefind;
import com.beiding.jsonanalyzer.flow.ValueNode;
import com.beiding.jsonanalyzer.flow.ValueNodeFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;


/**
 * 本身是有状态的
 */
public class Selector {


    /**
     * 抓取内容
     */

    private List<Fetcher> fetchers = new ArrayList<>();

    public <T extends ValueNode> T executeOne(T holder, ValueNodeFactory<T> valueNodeFactory) {

        JSONObject jsonObject = new JSONObject();
        T valueNode = valueNodeFactory.create();
        valueNode.set(jsonObject);

        //立即执行每个结果

        for (Fetcher fetcher : fetchers) {
            //立刻执行产生结果
            Object o = fetcher.getFuncBase().executeOne(holder);
            Map<Object, Object> map = fetcher.forOne(o);

            map.forEach((k, v) -> {
                if (v != Undefind.i) {
                    if (k instanceof Key) {
                        Analyzer.set(jsonObject, k, v);
                    } else if (k instanceof String) {
                        jsonObject.put((String) k, v);
                    }
                }
            });
        }
        return valueNode;
    }

    public <T extends ValueNode> void pugAgg(T holder) {

        //放入多个值

        for (Fetcher fetcher : fetchers) {
            fetcher.getFuncBase().pugAgg(holder);
        }

    }

    public void resetAgg() {
        for (Fetcher fetcher : fetchers) {
            fetcher.getFuncBase().resetAgg();
        }
    }

    /**
     * 聚合结果产生
     *
     * @param valueNodeFactory
     * @param <T>
     * @return
     */
    public <T extends ValueNode> T aggGet(ValueNodeFactory<T> valueNodeFactory) {

        //每个聚合对象产生的结果最多允许产生一个

        JSONObject jsonObject = new JSONObject();
        T t = valueNodeFactory.create();
        t.set(jsonObject);

        for (Fetcher fetcher : fetchers) {
            Object o = fetcher.getFuncBase().aggGet();

            //如果聚合的结果大于1,日志打印不做处理

            Map<Object, Object> map = fetcher.forOne(o);

            //数据放入最终结果

            map.forEach((k, v) -> {
                if (v != Undefind.i) {
                    if (k instanceof Key) {
                        Analyzer.set(jsonObject, k, v);
                    } else if (k instanceof String) {
                        jsonObject.put((String) k, v);
                    }
                }
            });
        }

        return t;

    }


    /**
     * 产生值的方式有两种:
     * 一种是放入一个值,会直接产生一个结果
     * 另一种则是放入聚合批,等批结束的时候统一产生结果
     */


    public boolean isAgg() {
        for (Fetcher fetcher : fetchers) {

            //只要有一个函数只聚合的,整个都是聚合的
            if (fetcher.getFuncBase().checkAgg()) {
                return true;
            }
        }
        return false;
    }


    public List<Fetcher> getFetchers() {
        return fetchers;
    }
}
